using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls.WebParts;
using System.Xml.XPath;
using Microsoft.SharePoint;
using System.Text;
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("PS.Practices.Provisioner.Test, PublicKey=" + "0024000004800000940000000602000000" +
                              "240000525341310004000001000100d307c64976845108d3da9c64af8b89c4edf74872899ede4ae3" +
                              "20f1c193b14b9c6c4d91d0157400a789808092f1a5e8e0ce7decedbf1d081d0928e4ab7ac64fe2ee" +
                              "2cb886cc3bf6009b2da4876afb5d8ce07d4a98226903ae5ca43372298acf20ff991aecf002dcca8d" +
                              "66152a5b646c0921120b2840577dcdee5b1266e09e6bb3")]
namespace PS.Practices.SiteBuilder.Features.Schema
{
    
    static class ParserUtil
    {
        //internal static Dictionary<string, object> GetProvisionedProperties(SPWeb web)
        //{
        //    Dictionary<string, object> retDic = new Dictionary<string, object>();

        //    foreach (DictionaryEntry prop in web.AllProperties)
        //    {
        //        if (prop.Key.ToString().StartsWith("ProvisionerProp_"))
        //        {
        //            var val = prop.Key.ToString().Replace("ProvisionerProp_", "");

        //            retDic.Add(val, prop.Value);
        //        }
                    
        //    }

        //    return retDic;
        //}
        
        internal static bool GetAttributeBool(XPathNavigator element, string attributeName, bool defaultValue)
        {
            bool var = defaultValue;
            string strValue = element.GetAttribute(attributeName, string.Empty);
            if (!string.IsNullOrEmpty(strValue))
            {
                bool.TryParse(strValue, out var);
            }
            return var;
        }

        internal static string GetAttribute(XPathNavigator element, string attributeName)
        {
            string strValue = element.GetAttribute(attributeName, string.Empty);
            if (!string.IsNullOrEmpty(strValue))
            {
                return strValue;
            }
            return string.Empty;
        }

        internal static WebPart UpdateWPTitle(WebPart part, SPWeb web, string setTo, Dictionary<string, string> dic)
        {
            if (part == null)
                return null;

            string val = part.Title;

            if (!string.IsNullOrEmpty(setTo))
            {
                setTo = ReplaceLiveFields(setTo, null, web);
                val = string.Format(setTo, val);
                
            }

            if (dic != null)
            {
                foreach (string key in dic.Keys)
                {
                    string value = dic[key];
                    val = val.Replace(key, value);
                }
            }

            part.Title = val;
            return part;
        }

        internal static void UpdateListTitle(SPList list, string setTo, Dictionary<string, string> dic)
        {
            string val = list.Title;

            SPWeb web = list.ParentWeb;
            if (!string.IsNullOrEmpty(setTo))
            {
                setTo = ReplaceLiveFields(setTo, list, web);
                val = string.Format(setTo, val);
            }
            
            if (dic!=null)
            {
                foreach (string key in dic.Keys)
                {
                    string value = dic[key];
                    value = ReplaceLiveFields(value, list, web);
                    val = val.Replace(key, value);
                }
            }
            
            list.Title = val;
        }


        internal static string ReplaceAllPropertyFields(string val, Dictionary<string,object> properties )
        {
            Regex r = new Regex(@"{{(?<ObjectName>\S+).(?<PropertyName>\S+)}}");
            MatchCollection mc = r.Matches(val);
            string retStr = val;

            for (int i = 0; i < mc.Count; i++)
            {
                string parsedStr = ReplacePropertiesField(mc[i].ToString(), properties).ToString();

                retStr = retStr.Replace(mc[i].ToString(), parsedStr);
            }

            return retStr;
        }

        internal static string ReplaceAllLiveFields(string val, SPWeb web)
        {
            Regex r = new Regex(@"{{(?<ObjectName>\S+).(?<PropertyName>\S+)}}");
            MatchCollection mc = r.Matches(val);
            string retStr = val;
            
            for(int i =0; i < mc.Count; i++)
            {
                string parsedStr = ReplaceLiveFields(mc[i].ToString(), web);

                retStr = retStr.Replace(mc[i].ToString(), parsedStr);
            }

            return retStr;
        }

        //internal static object ReplaceObjectLiveFields(string val, SPWeb web)
        //{
        //    if (val == null) throw new ArgumentNullException("val");
        //    string v = val;
        //    object ret = null;

        //    if (v.Contains("{{Property"))
        //    {
        //        ret = ReplacePropertiesField(v, GetProvisionedProperties(web));
        //    }
        //    else
        //    {
        //        ret = ReplaceLiveFields(val, web);
        //    }

        //    return ret;
        //}

        //internal static object ReplaceLiveFields(string val, SPWeb web, Dictionary<string, object> properties )
        //{
        //    if (val == null) throw new ArgumentNullException("val");
        //    string v = val;
        //    object ret = new object();

        //    if (v.Contains("{{Property"))
        //    {
        //        ret = ReplacePropertiesField(v, properties);
        //    }
        //    else
        //    {
        //        v = ReplaceLiveFields(v, web);
        //    }

        //    return ret;
        //}

        internal static string ReplaceLiveFields(string val, SPWeb web )
        {
            if (val == null) throw new ArgumentNullException("val");
            string v = val;
            
            if (v.Contains("{{SPWeb.Title}}") && web != null)
            {
                v = v.Replace("{{SPWeb.Title}}", web.Title);
            }

            if (v.Contains("{{SPSite.Title}}") && web != null)
            {
                v = v.Replace("{{SPSite.Title}}", web.Site.RootWeb.Title);
            }

            if (v.Contains("{{SPWeb.ServerRelativeUrl}}") && web != null)
            {
                v = v.Replace("{{SPWeb.ServerRelativeUrl}}", web.ServerRelativeUrl);
            }
            
            if (v.Contains("{{ParentWeb.Title}}") && web != null)
            {
                //ParentWeb property no longer requires Dispose() 
                SPWeb pweb = web.ParentWeb;
                v = v.Replace("{{ParentWeb.Title}}", pweb.Title);
            }

            if (v.Contains("{{SPWeb.Description}}") && web != null)
            {
                v = v.Replace("{{SPWeb.Description}}", web.Description);
            }

            if (v.Contains(@"{{SPWeb.Properties["))
            {
                v = ReplaceWebProperties(web, v);
            }

            return v;
        }

        internal static object ReplacePropertiesField(string str, Dictionary<string, object> properties)
        {
            Regex r = new Regex(@"{{Property.(?<PropertyName>.+)}}");
            Match m = r.Match(str);
            object ret = new object();

            if (m != null)
            {
                string oldString = m.Value;
                string propertyName = m.Groups["PropertyName"].Value;

                if (properties.ContainsKey(propertyName))
                {
                    ret = properties[propertyName];
                    
                    if(ret is string)
                        ret = str.Replace(oldString, ret.ToString());
                }
            }

            return ret;
        }

        internal static string ReplaceWebProperties(SPWeb web, string str)
        {
            //{{SPWeb.Properties[vti_title]}} 
            Regex r = new Regex(@"{{SPWeb.Properties\[(?<propname>\S+)\]}}");
            Match m = r.Match(str);
            if(m != null)
            {
                string oldString = m.Value;
                string propertyName = m.Groups["propname"].Value;
                if (!string.IsNullOrEmpty(propertyName))
                {
                    try
                    {
                        str = str.Replace(oldString, web.Properties[propertyName]);
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            return str;
        }

        internal static string ReplaceLiveFields(string val, SPList list, SPWeb web)
        {
            if (string.IsNullOrEmpty(val)) throw new ArgumentNullException("val");
            string v = val;
            if (v.Contains("{{SPList.Title}}") && list != null)
            {
                v = v.Replace("{{SPList.Title}}", list.Title);
            }

            v = ReplaceLiveFields(v, web);

            return v;
        }

        
    }
}
